/**
 * 性能监控中间件
 * 记录API请求的性能指标、错误和详细信息
 */

import { log } from '../utils/logger.js';

/**
 * 性能监控统计
 */
const stats = {
  requests: {
    total: 0,
    success: 0,
    error: 0,
  },
  responseTimes: [],
  errors: [],
};

/**
 * 脱敏请求头
 * @param {Object} headers - 原始请求头
 * @returns {Object} 脱敏后的请求头
 */
const maskHeaders = (headers) => {
  const masked = { ...headers };
  const sensitiveHeaders = ['authorization', 'cookie', 'x-api-key'];

  for (const header of sensitiveHeaders) {
    if (masked[header]) {
      const value = masked[header];
      // 只显示前6个字符和后4个字符
      if (value.length > 10) {
        masked[header] = `${value.substring(0, 6)}...${value.substring(value.length - 4)}`;
      } else {
        masked[header] = '***MASKED***';
      }
    }
  }

  return masked;
};

/**
 * 性能监控中间件
 */
export const performanceMonitor = (req, res, next) => {
  const startTime = process.hrtime.bigint(); // 高精度计时

  // 记录请求开始
  const requestId = `${Date.now()}-${Math.random().toString(36).substring(7)}`;
  req.requestId = requestId;

  const requestInfo = {
    requestId,
    method: req.method,
    path: req.path,
    query: req.query,
    ip: req.ip || req.connection.remoteAddress,
    userAgent: req.get('user-agent'),
    userId: req.user?.id, // 如果有认证信息
  };

  // 记录请求日志
  log.info('请求开始', requestInfo);

  // 监听响应完成
  res.on('finish', () => {
    const endTime = process.hrtime.bigint();
    const responseTime = Number(endTime - startTime) / 1_000_000; // 转换为毫秒

    // 更新统计
    stats.requests.total += 1;
    if (res.statusCode < 400) {
      stats.requests.success += 1;
    } else {
      stats.requests.error += 1;
    }
    stats.responseTimes.push(responseTime);

    // 保持最近1000条响应时间记录
    if (stats.responseTimes.length > 1000) {
      stats.responseTimes.shift();
    }

    // 性能日志
    const performanceInfo = {
      requestId,
      method: req.method,
      path: req.path,
      statusCode: res.statusCode,
      responseTime: `${responseTime.toFixed(2)}ms`,
      userId: req.user?.id,
      contentLength: res.get('content-length'),
    };

    // 根据响应时间和状态码决定日志级别
    if (res.statusCode >= 500) {
      log.error('请求完成 [服务器错误]', performanceInfo);
    } else if (res.statusCode >= 400) {
      log.warn('请求完成 [客户端错误]', performanceInfo);
    } else if (responseTime > 5000) {
      log.warn('请求完成 [响应缓慢]', performanceInfo);
    } else {
      log.info('请求完成', performanceInfo);
    }

    // 记录性能指标（用于性能日志文件）
    log.performance('API性能指标', {
      requestId,
      endpoint: `${req.method} ${req.path}`,
      responseTime: responseTime.toFixed(2),
      statusCode: res.statusCode,
      timestamp: new Date().toISOString(),
    });
  });

  // 监听错误
  res.on('error', (error) => {
    const endTime = process.hrtime.bigint();
    const responseTime = Number(endTime - startTime) / 1_000_000;

    stats.requests.error += 1;
    stats.errors.push({
      requestId,
      path: req.path,
      error: error.message,
      timestamp: new Date().toISOString(),
    });

    // 保持最近100条错误记录
    if (stats.errors.length > 100) {
      stats.errors.shift();
    }

    log.error('请求错误', {
      requestId,
      method: req.method,
      path: req.path,
      responseTime: `${responseTime.toFixed(2)}ms`,
      error: error.message,
      stack: error.stack,
    });
  });

  next();
};

/**
 * 批改性能专用监控（用于批改相关路由）
 */
export const correctionPerformanceMonitor = (req, res, next) => {
  const startTime = process.hrtime.bigint();

  // 记录批改请求详情
  const correctionInfo = {
    requestId: req.requestId,
    essayId: req.params.essayId,
    userId: req.user?.id,
    gradeLevel: req.body?.gradeLevel || req.user?.gradeLevel,
  };

  log.info('[批改监控] 批改请求开始', correctionInfo);

  // 监听响应完成
  const originalJson = res.json.bind(res);
  res.json = function (data) {
    const endTime = process.hrtime.bigint();
    const responseTime = Number(endTime - startTime) / 1_000_000;

    // 记录批改性能
    log.performance('[批改监控] 批改性能指标', {
      requestId: req.requestId,
      essayId: req.params.essayId,
      userId: req.user?.id,
      responseTime: responseTime.toFixed(2),
      success: data.success,
      score: data.data?.score || data.data?.correctionResult?.score_breakdown?.total_score,
      errorCount: data.data?.correctionResult?.corrections?.length || 0,
      timestamp: new Date().toISOString(),
    });

    // 如果响应时间超过30秒，记录警告
    if (responseTime > 30000) {
      log.warn('[批改监控] 批改响应时间超过30秒', {
        requestId: req.requestId,
        essayId: req.params.essayId,
        responseTime: responseTime.toFixed(2),
      });
    }

    return originalJson(data);
  };

  next();
};

/**
 * 获取性能统计
 */
export const getPerformanceStats = () => {
  const { responseTimes, requests } = stats;

  if (responseTimes.length === 0) {
    return {
      requests,
      responseTimes: {
        avg: 0,
        min: 0,
        max: 0,
        p50: 0,
        p90: 0,
        p95: 0,
        p99: 0,
      },
      recentErrors: stats.errors.slice(-10), // 最近10条错误
    };
  }

  const sorted = [...responseTimes].sort((a, b) => a - b);
  const sum = sorted.reduce((a, b) => a + b, 0);

  const percentile = (p) => {
    const index = Math.ceil((sorted.length * p) / 100) - 1;
    return sorted[Math.max(0, index)];
  };

  return {
    requests,
    responseTimes: {
      avg: (sum / sorted.length).toFixed(2),
      min: sorted[0].toFixed(2),
      max: sorted[sorted.length - 1].toFixed(2),
      p50: percentile(50).toFixed(2),
      p90: percentile(90).toFixed(2),
      p95: percentile(95).toFixed(2),
      p99: percentile(99).toFixed(2),
    },
    recentErrors: stats.errors.slice(-10),
  };
};

/**
 * 重置性能统计
 */
export const resetPerformanceStats = () => {
  stats.requests.total = 0;
  stats.requests.success = 0;
  stats.requests.error = 0;
  stats.responseTimes = [];
  stats.errors = [];
};

export default {
  performanceMonitor,
  correctionPerformanceMonitor,
  getPerformanceStats,
  resetPerformanceStats,
};

